﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace csharpcore7_ch14_ConcurrencyAndAsynchronyWPF
{
    /// <summary>
    /// TestUI.xaml 的交互逻辑
    /// </summary>
    public partial class TestUI : Window
    {
        Button _button = new Button { Content = "Go" };
        TextBlock _results = new TextBlock();
        public TestUI()
        {
            InitializeComponent();

            var pannel = new StackPanel();
            pannel.Children.Add(_button);
            pannel.Children.Add(_results);
            Content = pannel;
            //_button.Click += (sender, args) => GoWebClientAsync();

            _button.Click += (sender, args) =>
             {
                 _button.IsEnabled = false;
                 Task.Run(() => GoOldAsync());
             };
        }

        void Go()
        {
            for (int i = 0; i < 5; i++)
                _results.Text += (GetPrimesCount(i * 1000000 + 2, 1000000) +
                    " primes betwwen " + (i * 1000000) + " and " + ((i + 1) * 1000000 - 1) + Environment.NewLine
                    ); 
        }

        async void GoAsync()
        {
            _button.IsEnabled = false;
            for (int i = 0; i < 5; i++)
                _results.Text += await GetPrimesCountAsync(i * 1000000 + 2, 1000000) +
                                " primes betwwen " + (i * 1000000) + 
                                " and " + ((i + 1) * 1000000 - 1) + 
                                Environment.NewLine;
            _button.IsEnabled = true ;
        }

        async void GoWebClientAsync() 
        {
            _button.IsEnabled = false;
            string[] urls = "www.baidu.com www.qq.com www.163.com".Split();
            int totalLength = 0;

            try
            {
                foreach (string url in urls)
                {
                    var uri = new Uri("http://" + url);
                    byte[] data = await new WebClient().DownloadDataTaskAsync(uri);
                    _results.Text += "Length of " + uri + " is " + data.Length + Environment.NewLine;
                    totalLength += data.Length;
                }
                _results.Text += "Total Length: " + totalLength;
            }
            catch (WebException ex)
            {
                _results.Text += "Error:" + ex.Message;
            }
            finally {
                _button.IsEnabled = true;
            }
        }

        // GoOldAsync与GetPrimesCount都会运行在工作线程上
        void GoOldAsync()
        {
            for (int i = 0; i < 5; i++)
            {
                int result = GetPrimesCount(i * 1000000 + 2, 1000000);
                Dispatcher.BeginInvoke(new Action(() =>
                    _results.Text += result + " primes betwwen "
                                     + (i * 1000000) +
                                    " and " + ((i + 1) * 1000000 - 1)
                                    + Environment.NewLine
                ));
            }
            Dispatcher.BeginInvoke(new Action(() => _button.IsEnabled = true));
        }

        int GetPrimesCount(int start, int count)
        {
            return
                ParallelEnumerable.Range(start, count).Count(n =>
                    Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0));
        }

        //异步版本GetPrimesCount
        Task<int> GetPrimesCountAsync(int start, int count)
        {
            return Task.Run(() =>
             ParallelEnumerable.Range(start, count).Count(n =>
                    Enumerable.Range(2, (int)Math.Sqrt(n) - 1).All(i => n % i > 0)));
        }
    }
}
